﻿#include <iostream>
#include <stdexcept>
#include <vector>
#include <string>
#include <filesystem> 

#include "../../3rd/tinyxml2/tinyxml2.h"
#include "../Cmd/CommandManage.h"

#include "ConfigFileManage.h"

using namespace std;
using namespace tinyxml2;
namespace fs = std::filesystem;

vector<CmdParameter> ConfigFileManage::ParseConfigFile(int argc, char *argv[])
{    
    if(argc > 1)
    {
        const string& XmlPath = argv[1];
        vector<CmdParameter> CmdParam;
        
        // 判断命令是否为配置文件路径
        if (ParseXml(XmlPath, CmdParam))
        {
            return CmdParam;
        }
        // else if(isAnotherFilePath(XmlPath))
        // {
                // ...
        // }
        else
        {
            return {};           
        }
    }
    return {};
}

bool ConfigFileManage::ParseXml(const std::string& filePath, std::vector<CmdParameter>& commands) 
{
    fs::path absolutePath = fs::absolute(filePath);

    XMLDocument doc;
    if (doc.LoadFile(absolutePath.string().c_str()) != XML_SUCCESS) 
    {
        cout << "Failed to load XmlFilePath: " << absolutePath.string() << endl;
        return false;
    }
    cout << "ConfigFileManage::ParseXml filePath: " << absolutePath.string() << endl;

    XMLElement* root = doc.FirstChildElement("Commands");
    if (!root) throw std::runtime_error("Configuration XML file format error: Root element not found");

    for (XMLElement* commandElem = root->FirstChildElement("Command"); commandElem; commandElem = commandElem->NextSiblingElement("Command"))
    {
        CmdParameter cmdParm;

        XMLElement* nameElem = commandElem->FirstChildElement("Name");
        if (!nameElem) continue;
        cmdParm.m_name = nameElem->GetText();

        XMLElement* paramsElem = commandElem->FirstChildElement("Parameters");
        if (paramsElem)
        {
            for (XMLElement* paramElem = paramsElem->FirstChildElement("Parameter"); paramElem; paramElem = paramElem->NextSiblingElement("Parameter"))
            {
                const char* paramName = paramElem->Attribute("name");
                const char* paramValue = paramElem->GetText();
                if (!paramName || !paramValue) continue;
                cmdParm.m_parameters.push_back( { paramName, paramValue });
            }
        }

        commands.push_back(cmdParm);
    }

    return true;
}